﻿using RStudio.UnitSingleton;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Pool;


/// <summary>
/// 极简模型加载服务 - 直接使用PrimitiveType和GameObject
/// </summary>
public class ServicePrimitiveModeLoader : IGameService
{
    public int Priority => 90;


    [Tooltip("游戏对象池")] private readonly Dictionary<PrimitiveType, IObjectPool<GameObject>> _primitivePools = new();
    [Tooltip("游戏对象池")] private readonly Dictionary<string, IObjectPool<GameObject>> _customModelPools = new();
    [Tooltip("游戏对象池")] private readonly HashSet<GameObject> _activeInstances = new();
    [Tooltip("游戏对象池")] private readonly Dictionary<PrimitiveType, Transform> _primitiveRoots = new();

    private Transform _poolsRoot;
    private bool _disposed = false;


    public void Init()
    {
        this.InitRoot();
        this.InitPrimitivePools();
    }
    public void Dispose()
    {
        if (_disposed) return;

        DoUnload();

        foreach (var pool in _primitivePools.Values)
        {
            pool.Clear();
        }
        _primitivePools.Clear();

        foreach (var pool in _customModelPools.Values)
        {
            pool.Clear();
        }
        _customModelPools.Clear();

        if (_poolsRoot != null)
        {
            UnityEngine.Object.Destroy(_poolsRoot.gameObject);
        }

        _disposed = true;
    }


    #region 初始化构建

    /// <summary>
    /// 初始化|根节点
    /// </summary>
    private void InitRoot()
    {
        _poolsRoot = new GameObject("[ModelPools_Root]").transform;
        UnityEngine.Object.DontDestroyOnLoad(_poolsRoot.gameObject);
    }

    /// <summary>
    /// 初始化|基本几何体对象池群
    /// </summary>
    private void InitPrimitivePools()
    {
        IEnumerable<PrimitiveType> primitiveTypes = Enum.GetValues(typeof(PrimitiveType)).Cast<PrimitiveType>();
        foreach (var primitiveType in primitiveTypes)
        {
            CreatePrimitivePool(primitiveType);
        }
    }

    /// <summary>
    /// 创建|基本几何体对象池
    /// </summary>
    /// <param name="primitiveType"></param>
    private void CreatePrimitivePool(PrimitiveType primitiveType)
    {
        Transform poolroot = new GameObject($"池|{primitiveType}").transform;
        poolroot.SetParent(_poolsRoot);
        poolroot.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
        _primitiveRoots.TryAdd(primitiveType, poolroot);


        var pool = new ObjectPool<GameObject>(
            createFunc: () => GameObjectExtension.DoCreatePrimitiveInstance(primitiveType),
            actionOnGet: target => target.DoGetFromPool(),
            actionOnRelease: target => target.DoResetToPool(poolroot),
            actionOnDestroy: UnityEngine.Object.Destroy,
            collectionCheck: true,
            defaultCapacity: 10,
            maxSize: 100
        );

        _primitivePools[primitiveType] = pool;
    }

    #endregion

    #region 外部访问方法 | 模型新建与卸载

    /// <summary>
    /// 创建|基本几何体
    /// </summary>
    public GameObject DoCreate(PrimitiveType primitiveType, Vector3 position, Vector3? scale = null, Material material = null)
    {
        if (_disposed) return null;

        var pool = GetPrimitivePool(primitiveType);
        if (pool == null) return null;

        var primitive = pool.Get();
        if (primitive == null) return null;

        GameObjectExtension.ConfigureForUse(primitive, position, scale ?? Vector3.one, material);
        _activeInstances.Add(primitive);

        return primitive;
    }

    /// <summary>
    /// 创建|批量基本几何体
    /// </summary>
    public List<GameObject> DoCreate(PrimitiveType primitiveType, IEnumerable<Vector3> positions, Vector3? scale = null, Material material = null)
    {
        return positions.Select(pos => DoCreate(primitiveType, pos, scale, material))
                       .Where(obj => obj != null)
                       .ToList();
    }

    /// <summary>
    /// 卸载|模型
    /// </summary>
    public void DoUnload(GameObject model)
    {
        if (model == null || !_activeInstances.Contains(model)) return;

        var primitiveType = model.GetPrimitiveType();
        bool hasPool = _primitivePools.TryGetValue(primitiveType.Value, out var primitivePool);
        if (primitiveType.HasValue && hasPool)
        {
            primitivePool.Release(model);
            return;
        }

        // 回退：直接销毁
        UnityEngine.Object.Destroy(model);

        _activeInstances.Remove(model);
    }

    /// <summary>
    /// 卸载|指定类型的模型
    /// </summary>
    public void DoUnload(PrimitiveType primitiveType)
    {
        var instancesToRemove = _activeInstances
            .Where(obj => GameObjectExtension.IsPrimitiveType(obj, primitiveType))
            .ToList();

        foreach (var instance in instancesToRemove)
        {
            DoUnload(instance);
        }
    }

    /// <summary>
    /// 卸载|全部模型
    /// </summary>
    public void DoUnload()
    {
        var instancesToRemove = _activeInstances.ToList();

        foreach (var instance in instancesToRemove)
        {
            DoUnload(instance);
        }
    }

    #endregion

    #region 外部访问方法 | 模型获取

    /// <summary>
    /// 获取|指定类型的活跃实例
    /// </summary>
    public List<GameObject> DoGetActives(PrimitiveType primitiveType)
    {
        return _activeInstances
            .Where(obj => GameObjectExtension.IsPrimitiveType(obj, primitiveType))
            .ToList();
    }

    /// <summary>
    /// 获取|所有活跃实例
    /// </summary>
    public List<GameObject> DoGetActives() 
    {
        return _activeInstances.ToList();
    }

    #endregion



    /// <summary>
    /// 获取|池
    /// </summary>
    /// <param name="primitiveType"></param>
    private IObjectPool<GameObject> GetPrimitivePool(PrimitiveType primitiveType)
    {
        return _primitivePools.GetValueOrDefault(primitiveType);
    }

}